package org.jaaksi.kottlindemo.test

import org.jaaksi.kottlindemo.OnSelectListener2
import org.jaaksi.kottlindemo.StringUtils
import org.jaaksi.kottlindemo.model.Person

/**
 * 用apply较多，拥有其他各功能，且返回传入的对象
 */
class TestLet {

  fun let() {
    var person: Person? = Person()
    // 在函数体内使用it替代object对象去访问其公有的属性和方法?
    // 最常用：表示object不为null的条件下，才会去执行let函数体
    person?.let {
      it.name = "11"
      it.age = 18
      it.id = "100000"
      it.say()
    }

//    also函数和let很像，只是唯一的不同点就是let函数最后的返回值是最后一行的返回值而also函数的返回值是返回当前的这个对象。
//    一般可用于多个扩展函数链式调用
    var person2: Person? = Person().also {
      it.name = "11"
      it.age = 18
      it.id = "100000"
    }

    // run函数可以说是let和with两个函数的结合体
    person?.run {
      name = "11"
      age = 18
      id = "100000"
      say()
    }

    with(person!!) {
      // 在函数块内可以通过 this 指代该对象。也可以直接调用属性及方法
      this.name = "11"
      age = 18
      id = "100000"
      say()
    }

    // 整体作用功能和run函数很像，唯一不同点就是它返回的值是对象本身，而run函数是一个闭包形式返回，返回的是最后一行的值。
    // 正是基于这一点差异它的适用场景稍微与run函数有点不一样。
    // apply一般用于一个对象实例初始化的时候，需要对对象中的属性进行赋值。
    var person3 = Person().apply { // apply返回自身对象
      name = "11"
      say()
    }
  }

  // 内联函数的「函数参数」 不允许作为参数传递给非内联的函数，可以使用 noinline 标注内联函数的参数
  private inline fun test(block: () -> Unit) {
    println("inline用在带有lambda参数的函数，在编译时期，把调用这个函数的地方用这个函数的方法体进行替换。")
  }

  fun test() {
    // 1.必须是具有单个抽象⽅法的 Java 接⼝才能使用lambda表达式
    // 2.最后一个参数是一个函数的话，可以直接把括号的实现提到圆括号外面
    // 3.函数只有一个参数，可以直接省略圆括号
    setOnSelectListener(OnSelectListener2 { })
    StringUtils().setOnSelectListener {}
  }

  fun setOnSelectListener(onSelectListener2: OnSelectListener2) {

  }


}